<?php
    /**
     * Created by PhpStorm.
     * User: Administrator
     * Date: 2016/6/15 0015
     * Time: 11:54
     * 支持高性能的seaslog日志组件。
     */
    namespace wzh\tcfxapi;


    class Tongcheng {
        public static $agentAccount = 'e661da0f-d6ae-4062-83c5-f102610ffac8';//分销账号
        public static $Key = '4c48b894-00b8-42b6-8331-faa989ae7bc4';//下单key
        protected $tongcheng;
        protected static $url = 'http://jqapi.lvcang.cn/jingqu/Services/';
        //默认均为联合主动拉去
        //景区详情，票型查询，产品变更增量拉取，下线查询拉取，退改规则变化(有变化的产品id列表)，退改规则信息详情查询，获取价格日历，创建订单前校验，创建订单，重发短信，订单查询(同程id),根据联合订单id查询订单查询，退款接口，订单核销查询拉取（获取已核销订单），订单问题反馈（疑难订单处理），查询订单问题反馈结果
        public static $uriarr = array(
            'GetSceneryDetail'            => array(
                'uri'  => 'GetSceneryDetailService.ashx',
                'sign' => 'SceneryDetailSign'
            ),
            'GetTicketDetail'             => array(
                'uri'  => 'GetTicketDetailService.ashx',
                'sign' => 'TicketDetailSign'
            ),
            'GetTicketIncrement'          => array('uri' => 'GetTicketIncrementService.ashx', 'sign' => 'OffLineSign'),
            'OffLineGroupTicket'          => array('uri' => 'OffLineGroupTicketService.ashx', 'sign' => 'OffLineSign'),
            'RefundRuleChangeTicket'      => array('uri' => 'RefundRuleChangeTicketService.ashx', 'sign' => 'OffLineSign'),
            'GetRefundRule'               => array('uri' => 'GetRefundRuleService.ashx', 'sign' => 'ReRuleSign'),
            'GetPriceCalendarInfo'        => array(
                'uri'  => 'GetPriceCalendarInfoService.ashx',
                'sign' => 'PriceCalendarSign'
            ),
            'CreateOrderValidate'         => array(
                'uri'  => 'CreateOrderValidateService.ashx',
                'sign' => 'OrderValidateSign'
            ),
            'CreateOrder'                 => array('uri' => 'CreateOrderService.ashx', 'sign' => 'CreateOrderSign'),
            'SendMessage'                 => array('uri' => 'SendMessageService.ashx', 'sign' => 'SendMessageSign'),
            'QueryOrderList'              => array(
                'uri'  => 'QueryOrderListService.ashx',
                'sign' => 'QueryOrderSign'
            ),
            'GetOrderListByThirdSerialId' => array(
                'uri'  => 'GetOrderListByThirdSerialIdService.ashx',
                'sign' => 'OrderByThirdIdSign'
            ),
            'NewCreateOrderCancel'        => array(
                'uri'  => 'NewCreateOrderCancelService.ashx',
                'sign' => 'OrderCancelSign'
            ),
            'GetOrderVerification'        => array(
                'uri'  => 'GetOrderVerificationService.ashx',
                'sign' => 'OffLineSign'
            ),
            'AddOrderFeedBack'            => array(
                'uri'  => 'AddOrderFeedBackService.ashx',
                'sign' => 'AddFeedBackSign'
            ),
            'GetOrderFeedBackInfo'        => array(
                'uri'  => 'GetOrderFeedBackInfoService.ashx',
                'sign' => 'OffLineSign'
            ),
        );

        //写日志
        public static function writelog($data, $type = 'debug', $filename = 'tongchenglog.txt', $debug = true) {
            if ($debug) {
                if(is_array($data)){
                    $data=self::encode_json($data);
                }
                $path = dirname(dirname(dirname(dirname(dirname(__FILE__))))) . '/lianheapilog';
                if (class_exists('SeasLog', false)) {
                    \Seaslog::setBasePath($path);
                    \Seaslog::setLogger('TongchengFXapi');
                    \Seaslog::log($type, $data);
                }
                else {
                    $path .= '/TongchengFXapi/' . date('Ymd');
                    self::lianhemkdir($path);
                    $date = date('Y-m-d H:i:s');
                    $fp = fopen($path . '/' . $type . $filename, 'a');
                    fwrite($fp, $data . "：time:{$date}\t\n");
                    fclose($fp);
                }
            }
        }

        public static function lianhemkdir($path = false) {
            if (is_dir($path)) {
                return true;
            }
            else {
                $res = @mkdir($path, 0777, true);
                return $res;
            }
        }

        /**
         * @return tongcheng|null
         */
        public function create() {
            if (!isset(self::$tongcheng)) {
                self::$tongcheng = new Tongcheng();
            }
            return self::$tongcheng;
        }

        /**
         * 获取景区签名
         * @param $data
         * @return string
         */
        public function SceneryDetailSign($data) {
            $str = self::$agentAccount .  $data['sceneryId'] . self::$Key;
            return self::buildSign($str);
        }
   /**
         * 获取产品签名
         * @param $data
         * @return string
         */
        public function TicketDetailSign($data) {
            $str = self::$agentAccount . $data['pageSize'] . $data['pageIndex'] . self::$Key;
            return self::buildSign($str);
        }

        /**
         * 产品变动增量|产品下架增量|退改变动增量；查询接口签名|订单核销拉取接口|订单反馈处理结果拉取签名
         * @param $data
         * @return string
         */
        public function OffLineSign($data) {
            $str = self::$agentAccount . $data['maxIncrementId'] . $data['queryNumber'] . self::$Key;
            return self::buildSign($str);
        }

        /**
         * 退改信息查询签名
         * @param $data
         * @return string
         */
        public function ReRuleSign($data) {
            $str = self::$agentAccount . $data['ProductID'] . self::$Key;
            return self::buildSign($str);
        }

        /**
         * 价格日历接口签名
         * @param $data
         * @return string
         */
        public function PriceCalendarSign($data) {
            $str = self::$agentAccount . $data['PriceId'] . self::$Key;
            return self::buildSign($str);
        }

        /**
         * 下单校验签名
         * @param $data
         * @return string
         */
        public function OrderValidateSign($data) {
            $str = self::$agentAccount . $data['PriceId'] . $data['Tickets'] . $data['TravelerMobile'] . self::$Key;
            return self::buildSign($str);
        }

        /**
         * 下单签名
         * @param $data
         * @return string
         */
        public function CreateOrderSign($data) {
            $str = self::$agentAccount . $data['priceID'] . implode('', $data['travelerMobile']) . $data['thirdSerialId'][0] . self::$Key;
            return self::buildSign($str);
        }

        /**
         * 重发凭证签名
         * @param $data
         * @return string
         */
        public function SendMessageSign($data) {
            $str = self::$agentAccount . implode('', $data['serialId']) . $data['sendMobile'] . self::$Key;
            return self::buildSign($str);
        }

        /**
         * 同程订单查询签名
         * @param $data
         * @return string
         */
        public function QueryOrderSign($data) {
            $str = self::$agentAccount . $data['orderSerialId'] . $data['pageIndex'] . $data['pageSize'] . self::$Key;
            return self::buildSign($str);
        }

        /**
         * 第三方订单号查询签名
         * @param $data
         * @return string
         */
        public function OrderByThirdIdSign($data) {
            $str = self::$agentAccount . implode('', $data['thirdSerialId']) . self::$Key;
            return self::buildSign($str);
        }

        /**
         * 取消订单签名|退款回调接口签名
         * @param $data
         * @return string
         */
        public function OrderCancelSign($data) {
            $str = self::$agentAccount . $data['serialId'] . self::$Key;
            return self::buildSign($str);
        }

        /**
         *订单反馈接口签名
         * @param $data
         * @return string
         */
        public function AddFeedBackSign($data) {
            $str = self::$agentAccount . $data['OrderSerialId '] . self::$Key;
            return self::buildSign($str);
        }

        /**
         * 范围32位小写md5加密字符串
         * @param $str
         * @return string
         */
        public function buildSign($str) {
            return strtolower(md5($str));
        }

        public function request($data, $uri) {
            $header = array(
                "Content-Type: application/json; charset=utf-8",
            );
            $function = self::$uriarr[$uri]['sign'];
            $sign = $this->$function($data);
            //$requst_header = '{"digitalSign":"'.$sign.'","agentAccount":"'.self::$agentAccount.'"}';
            $requst_header = array('digitalSign'=>$sign,"agentAccount"=>self::$agentAccount);
            $requst_data = array('requestHead' => $requst_header, 'requestBody' => $data);
            $requst_data = self::encode_json($requst_data);
            self::writelog('request:' . $requst_data,'info', 'tongchengrequest.txt');
            if($function=='ReRuleSign'){
                $requst_data= str_replace('"ViewSceneryRule":0,','"ViewSceneryRule":false,',$requst_data);
            }
            //可以替换自己的curl工具
            $res_json = self::http_post( self::$url . self::$uriarr[$uri]['uri'], $requst_data, $header);
            self::writelog('reponse:' . $res_json, 'info', 'tongchengrequest.txt');
            //        $res = json_decode($res_json, true);
            return $res_json;
        }

        /**
         * POST 请求
         * @param string $url
         * @param json   $param
         * @param array  $header
         * @return string content
         */
        private static function http_post($url, $param, $header = false) {
            $oCurl = curl_init();
            if (stripos($url, "https://") !== FALSE) {
                curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
                curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
                curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
            }
            if (is_string($param)) {
                $strPOST = $param;
            }
            else {
                $aPOST = array();
                foreach ($param as $key => $val) {
                    $aPOST[] = $key . "=" . urlencode($val);
                }
                $strPOST = join("&", $aPOST);
            }
            if ($header) {
                curl_setopt($oCurl, CURLOPT_HTTPHEADER, $header);
            }
            curl_setopt($oCurl, CURLOPT_URL, $url);
            curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($oCurl, CURLOPT_POST, true);
            curl_setopt($oCurl, CURLOPT_POSTFIELDS, $strPOST);
            $sContent = curl_exec($oCurl);
            $aStatus = curl_getinfo($oCurl);
            curl_close($oCurl);
            if (intval($aStatus["http_code"]) == 200) {
                return $sContent;
            }
            else {
                return false;
            }
        }

        //中文处理5.4以下
        public function encode_json($str) {
            return urldecode(json_encode(self::url_encode($str)));
        }

        function url_encode($str) {
            if (is_array($str)) {
                foreach ($str as $key => &$value) {
                    if (is_array($value)) {
                        $value = self::url_encode($value);
                    }
                    else {
                        if (!is_numeric($value)) {
                            $value = urlencode($value);
                        }
                    }
                }
            }
            else {
                $str = urlencode($str);
            }
            return $str;
        }
        //修改使其支持多维数组
        public static function a2s($arr,$k='') {
            $str = "";
            foreach ($arr as $key => &$value) {
                if (is_array($value)) {
                    if(empty($k)){
                        $str .= self::a2s($value,urlencode($key));
                    }else{
                        $ak=$k."[".urlencode($key)."]";
                        $str .= self::a2s($value,$ak);
                    }
                    /*
                    foreach ($value as $value2) {
                        $str .= urlencode($key) . "[]=" . urlencode($value2) . "&";
                    }*/
                }
                else {
                    if(empty($k)){
                        $str .= urlencode($key) . "=" . urlencode($value) . "&";
                    }else{
                        $str .= $k."[".urlencode($key) . "]=" . urlencode($value) . "&";
                    }

                }
            }
            return $str;
        }

        public static function s2a($str) {
            $arr = array();
            //echo $str;
            parse_str($str, $arr);
            return $arr;
        }
    }
